<script setup lang="ts">
import {ElCascader} from "element-plus";
import {defineProps, ref, useAttrs, useSlots, watch} from "vue";
import {devCascaderMutexProps} from "./cascaderMutex";
import {devArraysEqual, devDeepClone, devIsItemInArray} from "@/utils";
import {devDeepMerge, useConfig} from "@/index";

const slots = useSlots();
const cascaderAttrs: Record<string, any> = useAttrs(); // 事件和属性
const props = defineProps(devCascaderMutexProps); // 组件props

const allSelectValue = ref<any>([])
const options_path = ref<any>({})
const copy_options = ref<any[]>([]);


/**
 * 设置禁用
 * @param optionsList
 * @param indexList
 */
const setDisabled = (optionsList: any[], indexList: number[]) => {
  // 确保 indexList 至少有一个元素
  if (indexList.length === 0) return;

  // 根据 indexList 获取最后一位下标
  const lastIndex = indexList[indexList.length - 1];

  // 遍历 indexList 除最后一位的所有索引，获取当前节点的子级
  let currentOptions = optionsList;
  for (let i = 0; i < indexList.length - 1; i++) {
    const index = indexList[i];
    // 确保 currentOptions 中的 children 存在
    if (currentOptions[index][cascaderAttrs?.props?.children || 'children']) {
      currentOptions = currentOptions[index][cascaderAttrs?.props?.children || 'children']; // 进入下一个子级
    } else {
      console.warn('索引路径无效'); // 如果路径不正确，输出警告
      return;
    }
  }

  // 确保最后一个索引有效，并修改对应的 disabled 属性
  if (currentOptions[lastIndex]) {
    const children = currentOptions[lastIndex][cascaderAttrs?.props?.children || 'children'] || [];
    // 判断子集是否全部被选中
    const allChildrenSelected = children.every((child: any) =>
        devIsItemInArray(allSelectValue.value, child.value)
    );

    // 如果子集全部被选中或禁用，禁用父级
    if (allChildrenSelected || children.every((child: any) => child.disabled)) {
      currentOptions[lastIndex][cascaderAttrs?.props?.disabled || 'disabled'] = true;

      // 判断是否需要禁用父级
      if(props.disableParentOnChild){
        // 递归向上禁用父级
        const parentIndexList = indexList.slice(0, -1); // 获取父节点的 indexList
        if (parentIndexList.length > 0) {
          setDisabled(optionsList, parentIndexList); // 递归禁用父级
        }
      }
    }
  } else {
    console.warn('最后一个索引无效'); // 如果路径不正确，输出警告
  }
};

/**
 * 处理选中项
 * @param item
 */
const handleItem = (item: any) => {
  let indexList: number[];
  if (!Array.isArray(item)) {
    indexList = options_path.value[item].devAllIndex;
  } else {
    indexList = options_path.value[item[item.length - 1]].devAllIndex;
  }
  // 处理当前项及其父级的禁用状态
  setDisabled(copy_options.value, indexList);
};

const initDisabled = () => {
  const currentValue = formatParameters(cascaderAttrs.modelValue)
  copy_options.value = devDeepClone(props.options || [])
  if (!!cascaderAttrs?.props?.emitPath) {
    allSelectValue.value.forEach((item: any[]) => {
      if (cascaderAttrs?.props.multiple) {
        if (item && !devIsItemInArray(currentValue as any[], item)) {
          handleItem(item);
        }
      } else {
        if (item && !devArraysEqual(currentValue as any[], item)) {
          handleItem(item);
        }
      }
    })
  } else {
    allSelectValue.value.forEach((item: any) => {
      const isSelected = cascaderAttrs?.props.multiple
          ? currentValue.includes(item)
          : currentValue === item;
      if (!isSelected) {
        handleItem(item);
      }
    });
  }
}

/**
 * 清理数组：如果参数不是数组，返回空数组；如果是数组，去除空数组和所有空值。
 * @param input - 输入的参数，可以是任意类型
 * @returns 清理后的数组
 */
function cleanArray<T>(input: unknown): T[] {
  // 如果输入不是数组，返回空数组
  if (!Array.isArray(input)) {
    return [];
  }

  // 去除空数组和所有空值
  return input.filter((item) => {
    // 过滤掉空数组
    if (Array.isArray(item) && item.length === 0) {
      return false;
    }
    // 过滤掉所有空值（null、undefined、空字符串等）
    return item !== null && item !== undefined && item !== "";
  }) as T[];
}

/**
 * 格式化参数
 */
const formatParameters =(value:any)=>{
  if(value){
    return value
  }else{
    return !cascaderAttrs?.props?.emitPath && !cascaderAttrs.multiple ? '' : [];
  }
}

watch([() => allSelectValue.value, () => props.options,() => options_path.value], () => {
  if (props.options && props.options.length > 0 && Object.keys(options_path.value).length>0) {
    initDisabled();
  }
}, {deep: true});

watch(() => props.allSelectValue, () => {
  allSelectValue.value = cleanArray(props.allSelectValue);
}, {deep: true, immediate: true});

watch( () => props.optionsPath, () => {
  options_path.value = props.optionsPath;
}, {deep: true, immediate: true});

// 定义组件名称
defineOptions({
  name: 'DevCascaderMutex',
  inheritAttrs: false
});
</script>

<template>
  <el-cascader
      v-bind="devDeepMerge(useConfig().elCascaderProps, $attrs)"
      :options="copy_options"
    >
    <template v-for="itemSlot in Object.keys(slots)" :key="itemSlot" v-slot:[itemSlot]="temp">
        <slot :name="itemSlot" v-bind="temp"></slot>
    </template>
  </el-cascader>
</template>

